package wxdgaming.game.login.login.sdk;

import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import wxdgaming.boot2.core.lang.RunResult;
import wxdgaming.boot2.core.token.JsonTokenBuilder;
import wxdgaming.boot2.core.util.PatternUtil;
import wxdgaming.boot2.core.util.SingletonLockUtil;
import wxdgaming.boot2.starter.batis.sql.SqlDataHelper;
import wxdgaming.game.common.bean.login.AppPlatformParams;
import wxdgaming.game.common.slog.SlogService;
import wxdgaming.game.login.LoginServerProperties;
import wxdgaming.game.login.bean.UserDataVo;
import wxdgaming.game.login.entity.UserData;
import wxdgaming.game.login.inner.InnerService;
import wxdgaming.game.login.login.LoginService;
import wxdgaming.game.login.slog.AccountLoginLog;
import wxdgaming.game.login.slog.AccountRegisterLog;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * 渠道参数
 *
 * @author wxd-gaming(無心道, 15388152619)
 * @version 2025-06-07 18:22
 **/
public abstract class AbstractSdkLoginApi {

    @Autowired protected LoginService loginService;
    @Autowired protected SqlDataHelper sqlDataHelper;
    @Autowired protected LoginServerProperties loginServerProperties;
    @Autowired protected InnerService innerService;
    @Autowired protected SlogService slogService;

    /** 平台 */
    public abstract AppPlatformParams.Platform platform();

    public abstract RunResult login(HttpServletRequest context, AppPlatformParams appPlatformParams) throws Exception;


    public void validateUsername(String username) {
        if (StringUtils.isBlank(username) || PatternUtil.AdminSet.contains(username.trim().toUpperCase())) {
            throw new IllegalArgumentException("用户名非法！");
        }
    }

    protected UserData createUserData(String ip, String account, AppPlatformParams appPlatformParams, String platformUserId) {

        validateUsername(account);/*TODO 检查合法性*/

        UserData userData = new UserData();
        userData.setAccount(account);
        userData.setAppId(appPlatformParams.getAppId());
        userData.setPlatform(appPlatformParams.getPlatform().name());
        userData.setPlatformUserId(platformUserId);
        userData.setCreateTime(System.currentTimeMillis());

        AccountRegisterLog accountLoginLog = new AccountRegisterLog(
                userData.getAccount(),
                userData.getPlatform(),
                userData.getPlatformChannelId(),
                ip
        );
        slogService.pushLog(accountLoginLog);

        return userData;
    }

    public UserData getUserData(String account, Supplier<UserData> supplier) {
        SingletonLockUtil.lock(account);
        try {
            UserData userData = loginService.userData(account);
            if (userData == null) {
                userData = supplier.get();
                sqlDataHelper.getCacheService().cache(UserData.class).put(userData.getAccount(), userData);
            }
            return userData;
        } finally {
            SingletonLockUtil.unlock(account);
        }
    }

    /** 登录成功 */
    public RunResult loginSuccess(UserData userData, String loginIp) {

        if (userData.getBanExpireTime() > System.currentTimeMillis()) {
            return RunResult.fail("账号被封禁！").code(5).fluentPut("banExpireTime", userData.getBanExpireTime());
        }

        userData.setLoginCount(userData.getLoginCount() + 1);
        userData.setLastLoginTime(System.currentTimeMillis());

        /*token 有效期保留10分钟，在游戏服登录可以续签*/
        JsonTokenBuilder jwtBuilder = JsonTokenBuilder.of(loginServerProperties.getJwtKey(), TimeUnit.MINUTES, 10);
        UserDataVo userDataVo = new UserDataVo();
        userDataVo.setAccount(userData.getAccount());
        userDataVo.setCreateTime(userData.getCreateTime());
        userDataVo.setAppId(userData.getAppId());
        userDataVo.setPlatform(userData.getPlatform());
        userDataVo.setPlatformChannelId(userData.getPlatformChannelId());
        userDataVo.setPlatformUserId(userData.getPlatformUserId());
        userDataVo.setWhite(userData.isWhite());
        userDataVo.setGmLevel(userData.getGmLevel());
        userDataVo.setLoginCount(userData.getLoginCount());

        jwtBuilder.put("user", userDataVo);
        String token = jwtBuilder.compact();

        AccountLoginLog accountLoginLog = new AccountLoginLog(
                userData.getAccount(),
                userData.getPlatform(),
                userData.getPlatformChannelId(),
                loginIp
        );
        slogService.pushLog(accountLoginLog);

        return RunResult.ok()
                .fluentPut("userId", userData.getPlatformUserId())
                .fluentPut("token", token)
                .fluentPut("serverList", innerService.gameServerList(userData));
    }

}
